import { APP_ID,AES_IV,AES_KEY,NEWS_UAID,NEWS_PAID,NEWS_VAID,NEWS_RAID,APP_TYPE,APP_NAME } from './config.js';
import { InterstitialAd } from './utils/interstitial-ad.js';
import Util from './utils/util.js';
import Event from './utils/event.js';
import db from './utils/db.js';
import api from './api/api.js';
import AES from './utils/aes.js';
import os from './os.js';

App({
  os,
  eventer: null,
  globalData: {
    appType: APP_TYPE, // 应用类型
    appName: APP_NAME, // 应用名称
    iaaMix: false, //免费版混合付费
    isTestEnv: false, //是否测试环境
    isOpenQueue: false, // 开启队列发送日志
    isFirstIntUser: true, // 是否第一次初始化
    systemInfo: null, // 系统信息
    envInfo: null, // 环境信息
    isLogin: true, //是否已登录
    iosDyPayType: 0, //0=不支持支付，1=通用交易支付，2=IM支付
    userInfo: '', // 用户信息
    showAdddeskBtn: false, // 显示加桌按钮
    imId: '',  // 客服抖音号
    showAdNum: 0, // 打开广告次数
    adCountdown: 3, // 广告倒计时
    isAdRogueVer: false, // 广告是否开启流氓版本
    AdBrand: '', //媒体标识
    AdSlotId: '', //激励广告位置
    AdGapId: '', //插屏广告位置
    showEcho: false, // 控制台输出
    adverConfig: false, // 广告位配置
    currentAdConf: {}, // 当前广告
    launchOptions: {}, // 启动参数
    newLaunchOptions: {}, // 实时最新启动参数
  },

  // 新版播放页数据
  playerData: {
    // isUnlockPreview: os.canIUse('playlet-plugin.onUnlockPreviewButtonClick'),
    isUnlockPreview: false,
    showAdBtn: true,
    dialogType: 1,
    retainData: false,
    currentVideo: false,
    currentAblum: false
  },

  // 返回首页挽留弹框信息
  backAdData: false,

  // 日志队列
  logsQueue: [],

  /**
   * 生命周期函数--监听页面初始化
   */
  onLaunch: async function () {
    const that = this;
    this.setGlobalData('systemInfo', os.getDeviceInfo());
    this.setGlobalData('envInfo', os.getEnvInfoSync());
    this.loadLocUserInfo();
    
    // 注册消息通知回调
    this.eventer = new Event();

    //启动参数
    const options = os.getLaunchOptionsSync();
    console.log('oa launchOptions', options.query);
    if(!Util.isNullOrEmpty(options.query)){
      this.updateLocOamarkConf(options.query);
    }
    this.userLogin();
    this.checkSession();
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
    const data = this.executeCurrentPageMethod('getMethodData', {});
    this.sendAppLogs('app', 6, data);
  },

  /**
   * 初始化用户
   */
  initUserData: async function(code = '') {
    os.showLoading({
      title: '请稍候...',
      mask: true
    });
    api.initUserData({
      code: code,
      launch_options: JSON.stringify(this.globalData.newLaunchOptions),
      // old_launch_options: JSON.stringify(this.globalData.launchOptions)
    }).then(res => {
      os.hideLoading({});
      if (res.code == 200) {
        this.updateUserInfo(res.data);
        this.sendAppLogs('app', 1); //启动日志
        this.checkNoPayOrder();
      }else{
        if (res.code === 203 && this.globalData.isFirstIntUser) {
          db.clear();
          this.setGlobalData('isFirstIntUser', false);
          this.setGlobalData('userInfo', '');
          this.userLogin();
        } else {
          this.Tips({title: '出错了，请重启小程序'});
        }
      }
    }).catch(err => {
      os.hideLoading({});
    });
  },

  userLogin: function() {
    const that = this;
    const uid = parseInt(this.globalData.userInfo?.uid || 0);
    const openid = this.globalData.userInfo?.openid || '';
    if (uid == 0 || openid == '') {
      os.login({
        force: true,
        success(res) {
          that.initUserData(res.code);
        },
        fail(res) {
          return that.Tips({title: '出错了，请重启小程序'});
        },
      });
      return;
    }
    os.checkSession({
      success () {
        that.setGlobalData('isLogin', true);
        that.initUserData();
      },
      fail () {
        that.setGlobalData('isLogin', false);
        os.login({
          force: true,
          success(res) {
            that.initUserData(res.code);
          },
          fail(res) {
            return that.Tips({title: '出错了，请重启小程序'});
          },
        });
      }
    });
  },

  /**
   * 从本地存储加载用户信息
   */
  loadLocUserInfo: function() {
    const userInfo = db.getUserInfo();
    if (userInfo) {
      this.setGlobalData('userInfo', userInfo);
    }
    
    const data = db.getOamarkConf();
    if (data) {
      this.setGlobalData('launchOptions', data);
      console.log('Loc launchOptions', data)
    }

    if (db.getEnvConf() === 'test') {
      this.setGlobalData('isTestEnv', true);
    }
  },

  /**
   * 更新用户信息
   */
  updateUserInfo: function(newUserInfo = {}) {
    this.echo('newUserInfo', newUserInfo);
    db.updateUserInfo(newUserInfo);
    this.setGlobalData('userInfo', newUserInfo);
    this.setGlobalData('imId', newUserInfo?.app_config.imId);
    this.setGlobalData('AdBrand', newUserInfo?.app_config.ad_brand || '');
    this.setGlobalData('AdSlotId', newUserInfo?.app_config.ad_slot_id || '');
    this.setGlobalData('AdGapId', newUserInfo?.app_config?.ad_gap_id || '');
    this.setGlobalData('iosDyPayType', newUserInfo?.app_config.ios_dypay_type || 0);
    this.setGlobalData('appType', newUserInfo?.app_config.app_type || APP_TYPE);
    this.setGlobalData('adCountdown', newUserInfo?.app_config?.ad_countdown || this.globalData.adCountdown);
    this.setGlobalData('isAdRogueVer', newUserInfo?.app_config?.ad_rogue_ver || this.globalData.isAdRogueVer);
    this.setGlobalData('appName', newUserInfo?.app_config?.app_name || APP_NAME);

    const desktopbtn = newUserInfo?.app_config?.show_adddesk_btn || 0;
    const output = newUserInfo?.app_config?.output_console || 0;
    if (output === 1) {
      this.setGlobalData('showEcho', true);
    }
    if (desktopbtn === 1) {
      this.setGlobalData('showAdddeskBtn', true);
    }
    
    this.echo('globalData', this.globalData);
    this.executeCurrentPageMethod('onUserInfoUpdated', this.globalData.userInfo);
  },

  /**
   * 更新本地投放渠道参数
   */
  updateLocOamarkConf: function(data) {
    const oamark = data?.link_id || '';
    const dye = parseInt(data?.oa_dye_type || 0); //0=24小时内不可染色，1=随时可染色

    if (oamark == '') {
      return;
    }

    this.setGlobalData('newLaunchOptions', data);

    const _data = db.getOamarkConf();
    if (_data) {
      // _data.creat_time = 1734599358000;
      // console.log(Util.formatTime(new Date(_data.creat_time)))
      if (dye === 0 && !Util.isOver24Hours(_data.creat_time)) {
        return;
      }
    }
    this.echo('set launchOptions', data);
    this.setGlobalData('launchOptions', data);
    data.creat_time = new Date().getTime();

    db.updateOamarkConf(data);
  },
  
  /**
   * 执行当前页面自定义方法
   */
  executeCurrentPageMethod: function(method, params = {}, res = false) {
    const pages = getCurrentPages();
    pages.forEach(page => {
      if (typeof page[method] === 'function') {
        res = page[method](params);
      }
    });
    return res;
  },
  
  /*
  * 检查用户登录状态
  */
  checkLogin: function () {
    let userInfo = this.globalData.userInfo;
    if (!userInfo) {
      userInfo = db.getUserInfo();
      this.setGlobalData('userInfo', userInfo);
    }
    if (userInfo && this.globalData.isLogin === true) {
      return true;
    }
    return false;
  },

  /*
  * 检查抖音登录状态
  */
  checkSession: function(){
    const that = this;
    os.checkSession({
      success () {
        that.setGlobalData('isLogin', true);
      },
      fail () {
        that.setGlobalData('isLogin', false);
      }
    });
  },

  /**
   * 刷新用户信息
   */
  refreshUserInfo(func = null){
    api.getUserInfo().then(res => {
      if (res.code == 200) {
        this.updateUserInfo(res.data);
        if(func !== null){
          func(res.data);
        }
      }
    });
  },

  /**
   * 退出登录
   */
  logout: function(){
    this.setGlobalData('userInfo', null);
    os.clearStorageSync();
  },

  /*
  * 检查未支付订单
  */
  checkNoPayOrder: function(func = function(){}){
    const orderId = db.getNoPayOrder();
    if (orderId) {
      db.delNoPayOrder();
      api.queryOrder({
        order_id: orderId
      },{showErr: false}).then(res => {
        this.echo('checkNoPayOrder', res);
        return func();
      }).catch(err => {
        return func();
      });
    }
    return func();
  },

  /**
   * 返回
   */
  goBack: function(delta = 1){
    os.navigateBack({
      delta: delta,
      fail(err) {
        os.switchTab({url: '/pages/index/index'})
      }
    });
  },

  /*
  * 延迟
  */
  sleep: function (timeout = 500) {
    return Util.sleep(timeout);
  },

  /**
   * 分享配置
   */
  getShareAppMessage: function (shareOption) {
    const dataset = shareOption.target.dataset;
    let param = {};
    switch(dataset.page){
      case 'index':
        param =  {
          path: '/pages/index/index'
        };
        break;
      case 'video':
        param =  {
          path: '/pages/player/player?playlet_id=' + dataset.videoitem.playlet_id + '&chapter_id='+ dataset.videoitem.chapter_id,
          imageUrl: dataset.videoitem.cover_img,
          title: dataset.title
        };
        break;
      default:

        break;
    }
    return param;
  },

  /**
   * 是否是苹果设备
   */
  isIPhone: function() {
    const systemInfo = this.globalData.systemInfo?.system || '';
    const brand = this.globalData.systemInfo?.brand || '';
    if (brand === "iPhone") {
      return true;
    }
    return systemInfo.includes('iOS');
  },

  /**
   * iOS是否支持购买虚拟商品
   */
  isCanBuy: function() {
    // return true;
    if (this.isIPhone()) {
      if (this.globalData.iosDyPayType === 0) {
        return false;
      }
    }
    return true;
  },

  /**
   * 设置全局变量
   * @param key   键
   * @param value 值
   */
  setGlobalData(key, value) {
    this.globalData[key] = value;
  },

  /*
  * 信息提示 + 跳转
  * @param object opt {title:'提示语',icon:''} | url
  * @param object to_url 跳转url 有5种跳转方式 {tab:1-5,url:跳转地址}
  */
  Tips: function (opt, to_url = {}) {
    return Util.Tips(opt, to_url);
  },

  /**
   * 控制台输出
   */
  echo: function (...args) {
    if (this.globalData.showEcho) {
      console.log(...args);
    }
  },

  /**
   * AES加密
   * @param word 
   */
  AESencrypt: function (word) {
    return AES.encrypt(word, AES_KEY, AES_IV);
  },

  /**
   * AES解密
   * @param word 
   */
  AESdecrypt: function (word) {
    return AES.decrypt(word, AES_KEY, AES_IV);
  },

  /**
   * 短剧章节列表
   */
  getChapterList: function (options) {
    let params = {
      playlet_id: options?.playlet_id  || 0,
      album_id: options?.tt_album_id  || 0
    };
    const success = options?.success  || function(){};
    const fail = options?.fail  || function(){};
    api.getChapterList(params).then(res => {
      if (res.code == 200 && res.data) {
        success(res.data);
      } else {
        fail(res);
      }
    }).catch(err => {
      fail(err);
    });
  },

  /**
   * 跳转到播放页
   */
  goPlayVideoPage: function (playletId, chapterId = 0, show = 0) {

    const _this = this;

    if (!os.canIUse('PlayletExtension')) {
      return this.Tips({title: '当前版本过低，请升级抖音'});
    }

    this.getChapterList({
      playlet_id: playletId,
      success: function(res) {
        if (res.list.length > 0) {
          let dramaId = res.album_id;
          let episodeId = res.list[0].episode_id;
          _this.playerData.currentAblum = res;

          if (chapterId > 0) {
            const currentVideo = res.list.find(item => item.chapter_id === chapterId);
            if (currentVideo !== undefined) {
              episodeId = currentVideo.episode_id;
            }
          } else {
            const is_watch = db.getSeenLastNum(playletId, res.is_watch);
            const currentVideo = res.list.find(item => item.num === is_watch);
            if (currentVideo !== undefined) {
              episodeId = currentVideo.episode_id;
            }
          }

          return os.navigateTo({
            url: `/pages/player/player?tt_album_id=${dramaId}&tt_episode_id=${episodeId}&playlet_id=${playletId}`
          });
        }
        return _this.Tips({title: `剧集已下架~`, icon: "fail"});
      },
      fail: function() {
        return _this.Tips({title: `剧集已下架~`, icon: "fail"});
      }
    });
  },

  /**
   * 跳转到协议页
   */
  goNewsPage: function (jumpType = 1) {
    let url = '';
    switch (jumpType) {
      case 1: // 用户协议
        url = '/pages/news/news?id=' + NEWS_UAID;
        break;
      case 2: // 隐私协议
        url = '/pages/news/news?id=' + NEWS_PAID;
        break;
      case 3: // 会员服务协议
        url = '/pages/news/news?id=' + NEWS_VAID;
        break;
      case 4: // 充值规则协议
        url = '/pages/news/news?id=' + NEWS_RAID;
        break;
    
      default:
        break;
    }
    os.navigateTo({
      url: url
    });
  },

  /**
   * 取日志数据
   */
  getLogsData: function (logType = 'app', markType = 1, data = {}) {
    const gData = this.globalData;
    let logsData = Util.getLogsData(logType, markType);

    logsData.app_id = APP_ID;
    logsData.uid = gData.userInfo?.uid || 0;
    logsData.session_id = gData.userInfo?.session || '';
    logsData.model = gData.systemInfo?.model || '';
    logsData.brand = gData.systemInfo?.brand || '';
    logsData.os = gData.systemInfo?.platform || '';
    logsData.system = gData.systemInfo?.system || '';

    logsData.oa_mark = gData.launchOptions?.link_id || '';
    logsData.oa_click_id = gData.launchOptions?.oa_click_id || '';
    logsData.oa_media_id = gData.launchOptions?.oa_media_id || '';
    logsData.oa_prefix_mark = gData.launchOptions?.oa_prefix_mark || '';
    logsData.oa_account = gData.launchOptions?.oa_account || '';
    logsData.oa_aid = gData.launchOptions?.oa_aid || '';
    logsData.oa_campaign_id = gData.launchOptions?.oa_campaign_id || '';
    logsData.oa_cid = gData.launchOptions?.oa_cid || '';
    logsData.oa_mid = gData.launchOptions?.oa_mid || '';
    logsData.oa_team_members = gData.launchOptions?.oa_team_members || '';
    logsData.oa_team_leader = gData.launchOptions?.oa_team_leader || '';
    
    logsData.deviceid = gData.userInfo?.openid || gData.userInfo?.device_id || '';
    logsData.device_imei = gData.launchOptions?.imei || '';
    logsData.device_oaid = gData.launchOptions?.oaid || '';
    logsData.device_androidid = gData.launchOptions?.androidid || '';
    logsData.device_idfa = gData.launchOptions?.idfa || '';
    
    if(logType === 'iaa' || logType === 'ad') {
      logsData.iaa_slot_id = gData.adverConfig?.slot_id || 0;
      logsData.iaa_ad_id = gData.currentAdConf?.advert_id || 0;
      logsData.iaa_strategy_id = gData.currentAdConf?.strategy_id || 0;
      logsData.iaa_code_id = gData.currentAdConf?.source_app_key || '';
      logsData.code_id = gData.currentAdConf?.code_id || '';
    }

    const currentPages = getCurrentPages();
    const curIndex = currentPages.length - 1
    logsData.appPath = currentPages[curIndex]?.route || '';
    if (logsData.log_type === 'appPageShow') {
      logsData.appFrom = currentPages[curIndex-1]?.route || '';
    }

    if (logsData.log_type === 'videoExit') {
      logsData.appTo = currentPages[curIndex]?.route || '';
    }

    logsData.behavior_time = Util.getCurrentTime();

    Object.assign(logsData, data);
    return logsData;
  },

  /**
   *  发送应用行为日志
   */
  sendAppLogs: function (logType = 'app', markType = 1, data = {}) {
    const that = this;
    const logsData = this.getLogsData(logType, markType, data);
    const excTypeData = ['videoDone', 'videoPlayLog', 'iaaShow', 'videoError'];
    const exclude = ['videoProgressSlide', 'videoPause', 'videoChangeSpeed', 'videoJump', 'appPageClick', 'appPageScroll'];

    if (exclude.includes(logsData.log_type)){
      return;
    }

    if (this.globalData.isOpenQueue) {
      this.sendQueueAppLogs(logsData);
      return;
    }

    setTimeout(() => {
      try {

        that.echo(logsData.log_type + '-' + logsData.log_desc, logsData);

        if (excTypeData.includes(logsData.log_type)) {
          api.sendAppLogs(logsData, {showErr: false}).then(res => {
            that.echo(`Api sendWriteLog[${logsData.log_type}]:`, res);
          }).catch(err => {
            that.echo('Api sendWriteLog Error:', err);
          });
        } else {
          api.sendGoAppLogs(logsData, {showErr: false}).then(res => {
            that.echo(`Api sendGoAppLogs[${logsData.log_type}]:`, res);
          }).catch(err => {
            that.echo('Api sendGoAppLogs Error:', err);
          });
        }

      } catch (err) {
        that.echo('Api sendWriteLog Error:', err);
      }
    }, 500);
  },

  sendQueueAppLogs: function (data) {
    const that = this;
    this.logsQueue.push(data);

    if (this.queueTimer !== undefined) {
      return;
    }

    this.isRequest = false;
    this.queueTimer = setInterval(function(){
      if (that.isRequest) {
        return;
      }
      if (that.logsQueue.length > 0) {
        const logsData = that.logsQueue.shift()
        that.isRequest = true;
        try {
          that.echo(logsData.log_type + '-' + logsData.log_desc, logsData);
          api.sendAppLogs(logsData, {showErr: false}).then(res => {
            that.isRequest = false;
            that.echo(`Api sendWriteLog[${logsData.log_type}]:`, res);
          }).catch(err => {
            that.isRequest = false;
            that.echo('Api sendWriteLog Error:', err);
          });
  
        } catch (err) {
          that.isRequest = false;
          that.echo('Api sendWriteLog Error:', err);
        }
      }

    }, 1000);
  },

  /**
   * 延迟显示插屏广告
   */
  delayAdDialog(show = true, data = {}) {
    if (this.globalData.appType === 1) {
      if (show) {
        this.adTimer = setTimeout(() => {
          this.showInterstitialAd(data);
        }, 30000);
      } else {
        if (this.adTimer) {
          clearTimeout(this.adTimer);
          this.adTimer = null;
        }
      }
    }
  },

  /**
   * 创建并显示插屏广告
   */
  showInterstitialAd(data = {}){
    const _this = this;

    if (this.globalData.appType !== 1) {
      return;
    }

    if (this.interAd !== undefined) {
      setTimeout(function(){
        _this.interAd.show();
      }, 50);
      return;
    }

    this.interAd = new InterstitialAd({
      onAdConfChange: (res) => {
        if (res.type === 1) {
          this.setGlobalData('adverConfig', res.data);
        } else {
          this.setGlobalData('currentAdConf', res.data);
        }
      },
      onLoad: (res) => {
        if(res.type === 'success'){
          _this.sendAppLogs('iaa', 2, {
            method_mark: '加载成功',
            method_mark_1: 200,
            ...data
          });
        }
        if(res.type === 'reg'){
          _this.sendAppLogs('iaa', 1, data);
        }
      },
      onShow: () => {
        _this.sendAppLogs('iaa', 4, data);
      },
      onClose: () => {
        _this.sendAppLogs('iaa', 6, {
            method_mark: 1, 
            method_mark_1: 0,
            ...data
        });
      },
      onError:(error) => {
        _this.sendAppLogs('iaa', 3, {
          method_mark: error.errMsg || '', 
          method_mark_1: error.errCode || '',
          ...data
        });
      }
    });
  },

  /**
   * 追剧/取消追剧
   * @param currentVideo 
   */
  addAndDelCollect(currentVideo = {}, func = null) {
    const pages = getCurrentPages();
    os.showLoading({title: "请稍候..."});
    if(currentVideo.is_collect > 0){
      api.delCollect({
        ids: currentVideo.collect_id , 
        type: 1
      }).then(res => {
        os.hideLoading({});
        if (res.code == 200) {
          if (typeof func === 'function') {
            func({is_collect: 0, collect_id: 0});
          } else {
            pages.forEach(page => {
              if (typeof page.onCollectUpdated === 'function') {
                page.onCollectUpdated(currentVideo, {is_collect: 0, collect_id: 0});
              }
            });
          }
          this.sendAppLogs('video', 7, {
            method_id: currentVideo.playlet_id, 
            method_cid: currentVideo.num,
            method_amount: currentVideo?.duration || 0,
            method_mark: currentVideo?.currentTime || 0
          });
          return this.Tips({title: '已取消追剧', icon: 'none'});
        }else{
          return this.Tips({title: res.msg});
        }
      }).catch(err => {
        os.hideLoading({});
      });
    } else {
      api.addCollect({
        playlet_id: currentVideo.playlet_id, 
        chapter_id: currentVideo.chapter_id,
        method_rid: parseInt(currentVideo?.fromPlayletId || 0),
        last_num: currentVideo.num, 
        type: 1
      }).then(res => {
        os.hideLoading({});
        if (res.code == 200) {
          if (typeof func === 'function') {
            func({is_collect: 1, collect_id: res.data.collect_id});
          } else {
            pages.forEach(page => {
              if (typeof page.onCollectUpdated === 'function') {
                page.onCollectUpdated(currentVideo, {is_collect: 1, collect_id: res.data.collect_id});
              }
            });
          }
          this.sendAppLogs('video', 6, {
            method_id: currentVideo.playlet_id, 
            method_cid: currentVideo.num,
            method_rid: parseInt(currentVideo?.fromPlayletId || 0),
            method_amount: currentVideo?.duration || 0,
            method_mark: currentVideo?.currentTime || 0
          });
          // return this.Tips({title: '追剧成功', icon: 'success'});
        }else{
          return this.Tips({title: res.msg});
        }
      }).catch(err => {
        os.hideLoading({});
      });
    }
  }

})
